package com.globallogic.oopbasics.competence.container;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.globallogic.oopbasics.competence.comparator.ValueComparator;
import com.globallogic.oopbasics.competence.entity.AbstractCompetency;

/**
 * @author olena.strelchuk
 */

/**
 * Calculate Total Competence
 */
public class TotalCompetence {
	/**
	 * TotalCompetence is a Container for Competencies
	 */
	private List<AbstractCompetency> container = new ArrayList<AbstractCompetency>();

	public List<AbstractCompetency> getContainer() {
		return container;
	}

	/**
	 * Basic constructor for TotalCompetence class to create new List objects To
	 * store Competencies.
	 */
	public TotalCompetence() {
	}

	/**
	 * Method to add Competencies to TotalCompetence
	 */
	public void add(AbstractCompetency compValue) {
		container.add(compValue);
	}

	/**
	 * Method to get TotalCompetence Value according to it's Competencies Level.
	 */
	public double getValue() {
		double value = 0;
		for (AbstractCompetency compValue : container) {
			value += compValue.getGlobalValue();
		}
		return value;
	}

	/**
	 * Method to sort Competencies by their Level.
	 */
	public void sortByLevelStandard() {
		Collections.sort(container);
	}

	/**
	 * Method to sort Competencies in TotalCompetence by their Level using
	 * comparator LevelComparator object.
	 */
	public void sortByLevel() {
		Collections.sort(container, new ValueComparator());
	}

	/**
	 * This method returns Competencies in TotalCompetence that satisfy some
	 * range or conditions (i.e. Level). As a result the method returns List
	 * with all appropriate Competencies.
	 */
	public TotalCompetence getCompetencies(double min, double max) {
		TotalCompetence rangeCompetence = new TotalCompetence();
		for (AbstractCompetency compValue : container) {
			if ((compValue.getGlobalValue() >= min)
					&& (compValue.getGlobalValue() <= max)) {
				rangeCompetence.add(compValue);
			}
		}
		return rangeCompetence;
	}

	/**
	 * @param instanseClass
	 *            Specific Class for new Collection containing elements of same
	 *            type
	 * @return New Collection with same class elements
	 * 
	 *         Search the elements of specific class in a collection and return
	 *         new collection containing that elements
	 */

	public TotalCompetence getCompetenciesOfOneType(Class<?> instanseClass) {
		TotalCompetence rangeCompetence = new TotalCompetence();

		for (AbstractCompetency compValue : container) {
			if (instanseClass.isAssignableFrom(compValue.getClass())) {
				rangeCompetence.add(compValue);
			}
		}
		return rangeCompetence;
	}

	/**
	 * This method is used to output the Competencies List in TotalCompetence.
	 */
	public String toString() {
		String res = new String();
		for (AbstractCompetency compValue : container) {
			res += compValue.getName() + " - " + compValue.getGlobalValue()
					+ "\n";
		}
		res += "---------------------------------------\n";
		return (res + "This Competence has a Value: " + getValue() + "\n");
	}

	/**
	 * Equals for TotalCompetence
	 */
	public boolean equals(Object other) {
		if (this == other) {
			return true;
		}
		if (!(other instanceof TotalCompetence)) {
			return false;
		}
		return ((TotalCompetence) other).container.equals(this.container);
	}

	/**
	 * HashCode for TotalCompetence
	 */
	public int hashCode() {
		return container.hashCode();
	}
}
